<?php
/**
 * @link https://ym2.cleverstone.top
 * @copyright Copyright (c) 2020 Yii Manager Software LLC
 */

namespace builder\form\util\control\dselect;

use builder\helper\Url;
use builder\base\UndefinedParamsException;
use builder\form\util\control\Control;
use builder\form\util\control\dselect\options\DsType;
use builder\form\util\control\dselect\options\Modal;
use builder\form\util\control\dselect\options\Page;
use yii\base\InvalidArgumentException;

/**
 * 动态select下拉控件
 * @author cleverstone
 * @since ym2.0
 */
class SelectDynamic extends Control
{
    /**
     * @var array
     */
    private $_options = [
        'control' => 'dynamic_select',
        'label' => '',
        'placeholder' => '请选择',
        'default' => '',
        'required' => false,
        'comment' => '',
        'layout' => 12,
        'style' => '',
        'class' => '',
        'attribute' => '',
        'multiple' => false,
        //==================
        'dataUrl' => '',
        'refreshBtn' => false,
        'additionBtn' => [],
        'btnPosition' => [],
        'uiConfig' => [
            'allowClear' => true,//允许清除选中
            'selectedInOrder' => true, //多选时,是否按选择顺序排序
            'selectedHideOption' => true, //多选时,是否隐藏已选择过的选项
            'closeOnSelect' => true, //选择后,是否关闭选项内容
        ],
    ];

    /**
     * 选择后,不关闭选项内容
     * @return $this
     */
    public function unCloseOnSelect()
    {
        $this->_options['uiConfig']['closeOnSelect'] = false;
        return $this;
    }

    /**
     * select2 配置
     * @param string $key 配置
     * @param mixed $value 值
     * @return $this
     */
    public function uiConfig($key, $value)
    {
        $this->_options['uiConfig'][$key] = $value;
        return $this;
    }

    /**
     * 新增按钮位置
     * @param string $position
     * @return $this
     */
    public function additionBtnPosition($position = 'left')
    {
        $this->_options['btnPosition']['additionBtn'] = (string)$position;
        return $this;
    }

    /**
     * 刷新按钮位置
     * @param string $position
     * @return $this
     */
    public function refreshBtnPosition($position = 'right')
    {
        if (!empty($this->_options['btnPosition']['refreshBtn'])) {
            $this->_options['btnPosition']['refreshBtn'] = (string)$position;
        }

        return $this;
    }

    /**
     * 动态新增按钮
     * @param array|\Closure|DsType $options
     * @see Modal
     * @see Page
     * @throws UndefinedParamsException
     * @throws \ReflectionException
     * @return $this
     */
    public function additionBtn($options)
    {
        if ($options instanceof DsType) {
            $options = $options->_toArray();
        } elseif ($options instanceof \Closure) {
            $options = $this->closureDi($options, DsType::class);
            if (!is_array($options) && $options instanceof DsType) {
                $options = $options->_toArray();
            }
        }

        if (!is_array($options)) {
            throw new InvalidArgumentException('Expected parameter [options] is array, But the others are given. ');
        }

        $this->_options['additionBtn'] = $options;
        $this->_options['btnPosition']['additionBtn'] = 'right';

        return $this;
    }

    /**
     * 刷新按钮
     * @return $this
     */
    public function refreshBtn()
    {
        $this->_options['refreshBtn'] = true;
        $this->_options['btnPosition']['refreshBtn'] = 'left';

        return $this;
    }

    /**
     * 数据链接
     * @param array|string $route
     * @return $this
     */
    public function dataUrl($route)
    {
        $this->_options['dataUrl'] = Url::to($route, '');
        return $this;
    }

    /**
     * 多选
     * @return $this
     */
    public function multiple()
    {
        $this->_options['multiple'] = true;
        return $this;
    }

    /**
     * 控件标签
     * @param string $label
     * @return $this
     */
    public function label($label)
    {
        $this->_options['label'] = (string)$label;
        return $this;
    }

    /**
     * 站位文本
     * @param string $placeholder
     * @return $this
     */
    public function placeholder($placeholder)
    {
        $this->_options['placeholder'] = (string)$placeholder;
        return $this;
    }

    /**
     * 默认值
     * @param string|array $default
     * @return $this
     */
    public function defaultValue($default)
    {
        $this->_options['default'] = $default;
        return $this;
    }

    /**
     * 是否必填
     * @param bool $required
     * @return $this
     */
    public function required($required = true)
    {
        $this->_options['required'] = (boolean)$required;
        return $this;
    }

    /**
     * 字段注释
     * @param string $comment
     * @return $this
     */
    public function comment($comment)
    {
        $this->_options['comment'] = (string)$comment;
        return $this;
    }

    /**
     * 布局，1-12
     * @param int $layout
     * @return $this
     */
    public function layout($layout)
    {
        $this->_options['layout'] = (int)$layout;
        return $this;
    }

    /**
     * CSS样式
     * @param array|string $style
     * @return $this
     */
    public function style($style)
    {
        $this->formatStyle($style);
        $this->_options['style'] = $style;

        return $this;
    }

    /**
     * UI
     * @param array|string $class
     * @return $this
     */
    public function uiClass($class)
    {
        $this->formatUiClass($class);
        $this->_options['class'] = $class;

        return $this;
    }

    /**
     * HTML属性
     * @param array|string $attribute
     * @return $this
     */
    public function attribute($attribute)
    {
        $this->formatHtmlAttribute($attribute);
        $this->_options['attribute'] = $attribute;

        return $this;
    }

    /**
     * @return array
     */
    public function _toArray()
    {
        $options = $this->_options;
        // 多选默认值检查
        if ($options['multiple'] && !empty($options['default'])) {
            if (!is_array($options['default'])) {
                throw new InvalidArgumentException('下拉选择是多选时，默认值必须是数组类型！');
            }
        }

        $tmp = ['left' => [], 'right' => []];
        foreach ($options['btnPosition'] as $key => $position) {
            if (!strcasecmp($position, 'left')) {
                $tmp['left'][] = $key;
            } else {
                $tmp['right'][] = $key;
            }
        }

        $options['btnPosition'] = $tmp;
        return $options;
    }
}